<?php

namespace App\Http\Controllers\Api;

use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Validation\Rule;
use App\Services\VolunteerService;
use App\Services\AccessTokenService;
use App\Services\WeixinConfigService;
use App\Lib\Util\ResponseUtil;
use App\User;
use App\UserPlatformOpenid;
use App\AccessToken;

class UserController extends Controller
{
    private $volunteerService = null;
    private $accessTokenService = null;
    private $weixinConfigService = null;

    public function __construct(VolunteerService $volunteerService,
        AccessTokenService $accessTokenService,
        WeixinConfigService $weixinConfigService)
    {
        $this->volunteerService = $volunteerService;
        $this->accessTokenService = $accessTokenService;
        $this->weixinConfigService = $weixinConfigService;
    }

    public function getRegisterVerifyCode(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSendVerifyCode($input);

        $this->volunteerService->sendBindUserVerifyCode($input['mobile']);

        return ResponseUtil::jsonResponse(true, 0, '发送验证码成功', []);
    }

    public function bindUserWithMobileAndOpenId(Request $request)
    {
        $input = $request->all();

        $this->validateWhenBindUser($input);

        $this->volunteerService->bindUserVerifyCode($input['mobile'], $input['platformId'], $input['openid'], $input['avatar'], $input['nickname']);

        $user = $this->volunteerService->checkUserByMobile($input['mobile']);

        if (isset($user)) {
            $accessToken = $this->accessTokenService->createBackstageAccessToken($user->id, $input['platformId'], $request->ip);
            return ResponseUtil::jsonResponse(true, 0, '成功绑定用户', [
                'user_id' => $accessToken->user_id,
                'access_token' => $accessToken->access_token
            ]);
        }

        return ResponseUtil::jsonResponse(false, 1, '无法绑定用户手机号', []);
    }

    public function loginWithOpenId(Request $request)
    {
        $input = $request->all();

        $this->validateWhenLogin($input);

        $user = $this->volunteerService->getUserInfoByOpenId($input['openid'], $input['platformId']);

        if (isset($user)) {
            $accessToken = $this->accessTokenService->createBackstageAccessToken($user['user_id'], $input['platformId'], $request->ip);
            return ResponseUtil::jsonResponse(true, 0, '成功绑定用户', [
                'user_id' => $accessToken->user_id,
                'access_token' => $accessToken->access_token,
                'user_info' => $user
            ]);
        }

        return ResponseUtil::jsonResponse(false, 1, '没有找到对应用户', []);
    }

    public function getUserOpenIdByAuthCode(Request $request)
    {
        $openIdInfo = $this->weixinConfigService->getAppOpenId($request->platformId, $request->authCode);

        if (isset($openIdInfo)) {
            return ResponseUtil::jsonResponse(true, 0, '', $openIdInfo);
        }

        return ResponseUtil::jsonResponse(false, 1, '没有找到当前用户对应公众号的配置以及openid', []);
    }

    private function validateWhenLogin(Array $input)
    {
        return Validator::make($input, [
            'openid' => 'required|max:100',
            'platformId' => [
                'required',
                Rule::in(collect(AccessToken::$APP_TYPE_MAP)->pluck('key')->toArray())
            ]
        ], [
            'platformId.required' => '没有输入平台ID',
            'platformId.in' => '平台ID值不正确',
            'openid.required' => '没有输入公众号Openid',
            'openid.max' => '公众号Openid长度过长'
        ])->validate();
    }

    private function validateWhenSendVerifyCode(Array $input)
    {
        return Validator::make($input, [
            'mobile' => 'required|max:20'
        ], [
            'mobile.required' => '没有输入手机号',
            'mobile.max' => '手机号长度不可超过:max'
        ])->after(function ($validator) use($input) {
            if ($this->volunteerService->isVerifyCodeTooFrequency($input['mobile'])) {
                $validator->errors()->add('id', '验证码发送过于频繁');
            }
        })->validate();
    }

    private function validateWhenBindUser(Array $input)
    {
        return Validator::make($input, [
            'mobile' => 'required|max:20',
            'platformId' => [
                'required',
                Rule::in(collect(AccessToken::$APP_TYPE_MAP)->pluck('key')->toArray())
            ],
            'openid' => 'required|max:100',
            'avatar' => 'max:255',
            'nickname' => 'max:100',
            'verifyCode' => 'required'
        ], [
            'mobile.required' => '没有输入手机号',
            'mobile.max' => '手机号长度不可超过:max',
            'platformId.required' => '没有输入平台ID',
            'platformId.in' => '平台ID值不正确',
            'openid.required' => '没有输入公众号Openid',
            'openid.max' => '公众号Openid长度过长',
            'avatar.max' => '用户头像长度不可超过:max',
            'nickname.max' => '用户昵称长度不可超过:max',
            'verifyCode.required' => '没有输入验证码',
        ])->after(function ($validator) use($input) {
            if (!$this->volunteerService->isModifyVerifyCodeValid($input['mobile'], $input['verifyCode'])) {
                $validator->errors()->add('id', '验证码不正确');
            }

            if ($this->volunteerService->isVerifyCodeExpired($input['mobile'])) {
                $validator->errors()->add('id', '验证码已过期');
            }
        })->validate();
    }
}
